



namespace Math
{


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////// functions decralation ////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////// operators /////////// ////////////////////////////////////////

template <typename T, typename K>
const Vector<T,K>& Vector<T,K>::operator=(const Vector<T,K>& right)
  {
      StructDataVector<T,K>::CopyToCoord(right.Getcoord());

      return *this;
  }



template <typename T, typename K>
const Vector<T,K>& Vector<T,K>::operator=(Vector<T,K>&& right)
  {
      StructDataVector<T,K>::CopyToCoord(right.Getcoord());

      return *this;
  }



template <typename T, typename K>
Vector<T,K> Vector<T,K>::operator+(const Vector<T,K>& right) const
  {
      Vector<T,K> help_vector;
      T** coord = StructDataVector<T,K>::Getcoord();

      ushorti i;
      for(i = 0; i < 4; i++) help_vector[i] = right[i] + (*coord[i]);

      return help_vector;
  }



template <typename T, typename K>
Vector<T,K> Vector<T,K>::operator+(const T* const right) const
  {
      Vector<T,K> help_vector;

      ushorti i;
      for(i = 0; i < 4; i++) help_vector[i] = right[i];

      return help_vector;
  }



template <typename T, typename K>
Vector<T,K> Vector<T,K>::operator*(const K right) const
  {
      Vector<T,K> help_vector;
      T** coord = StructDataVector<T,K>::Getcoord();

      ushorti i;
      for(i = 0; i < 4; i++) help_vector = (*coord[i]) * right;

      return help_vector;
  }


//////////////////////////////////////////////////////// Friend operators //////////////////////////////////////////////

template <typename T, typename K>
const Vector<T,K> operator+(const T* const left, const Vector<T,K>& right)
  {
      Vector<T,K> help_vector(right);
      T** help_pointer = right.Getcoord();

      ushorti i;
      for(i = 0; i < 4; i++) help_vector[i] = left[i] + (*help_pointer[i]);

      return help_vector;
  }



template <typename T, typename K>
const Vector<T,K> operator*(const K left, const Vector<T,K>& right)
  {
      Vector<T,K> help_vector;
      T** help_pointer = right.Getcoord();

      ushorti i;
      for(i = 0; i < 4; i++) help_vector[i] = left * (*help_pointer[i]);

      return help_vector;
  }

//////////////////////////////////////////////////////// standard functions //////////////////////////////////////////////

template <typename T, typename K>
T Vector<T,K>::VcdotV(const Vector<T,K>& vec)
  {
      return OWVector<T,K>::VcdotV(this, &vec);
  }



template <typename T, typename K>
T Vector<T,K>::VcdotV(const Vector<T,K>* const vec)
  {
      return OWVector<T,K>::VcdotV(this, vec);
  }



template <typename T, typename K>
Vector<T,K> Vector<T,K>::VxV(const Vector<T,K>& vec)
  {
      return OWVector<T,K>::VxV(*this, vec);
  }



template <typename T, typename K>
Vector<T,K> Vector<T,K>::VxV(const Vector<T,K>* const vec)
  {
      return OWVector<T,K>::VxV(*this, *vec);
  }



template <typename T, typename K>
T Vector<T,K>::size() const
  {
      T** coord = StructDataVector<T,K>::Getcoord();
      return sqrt((coord[X]*coord[X]) + (coord[Y]*coord[Y]) + (coord[Z]*coord[Z]));
  }



template <typename T, typename K>
void Vector<T,K>::LoadZeroVector()
  {
      T** coord = StructDataVector<T,K>::Getcoord();
      coord[X] = static_cast<T>(0);
      coord[Y] = static_cast<T>(0);
      coord[Z] = static_cast<T>(0);
      coord[W] = static_cast<T>(0);
  }


} // end namespace Math
